<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>hello_react</title>
</head>
<body>
    <!-- 准备一个“容器” -->
    <div id="test"></div>

    <!-- 引入 react 核心库 -->
    <script src="../js/react.development.js"></script>
    <!-- 引入 react-dom. 用于支持 react 操作 dom -->
    <script src="../js/react-dom.development.js"></script>
    <!-- 引入babel. 用于将 jsx 转换为 js -->
    <script src="../js/babel.min.js"></script>
    <script type="text/babel"> /* 这里必须写 babel */
        /*
            1. 初始化阶段： 由 ReactDOM.render() 触发 ———— 初次渲染
                1. constuctor() 构造器
                2. componentWillMount() 组件将要挂载的钩子
                3. render() 
                4. componentDidMount() 组件挂载完毕的钩子
            2. 更新阶段： 由组件内部 this.setState() 或父组件 render 触发
                1. shouldComponentUpdate() 控制组件更新的 “阀门”
                2. componentWillUpdate() 组件将要更新的钩子
                3. render()
                4. componentDidUpdate() 组件更新完毕的钩子
            3. 卸载组件： 由 ReactDOM.ummountComponentAtNode() 触发
                1. componentWillUnmount() 组件将要卸载的钩子
        */

        // 创建组件
        class Count extends React.Component {
            // 构造器
            constructor(props){
                console.log("构造器 —— constructor")
                super(props)
                // 初始化状态
                this.state = {num:1}
            }


            // +1 按钮的回调
            add = () => {
                let {num} = this.state;
                this.setState({num: num + 1})
            }
            // 卸载组件按钮的 回调
            death = () => {
                ReactDOM.unmountComponentAtNode(document.getElementById("test"))
            }

            // 强制更新
            force = () => {
                this.forceUpdate()
            }

            // 组件将要挂载的钩子
            componentWillMount(){
                console.log("组件将要挂载的钩子 —— componentWillMount")
            }
            // 组件挂载完毕的钩子
            componentDidMount(){
                console.log("组件挂载完毕的钩子 —— componentDidMount")
            }
            // 组件将要卸载时 的钩子
            componentWillUnmount(){
                console.log("组件将要卸载的钩子 —— componentWIllUnmount")
            }
            // 控制 组件更新 的 “阀门”
            shouldComponentUpdate(){
                console.log("控制组件更新的“阀门” —— shouldComponentUpdate")
                return true
            }
            // 组件将要更新时 的钩子
            componentWillUpdate(){
                console.log("组件将要更新的钩子 —— componentWillUpdate")
            }
            // 组件更新完毕的 钩子
            componentDidUpdate(){
                console.log("组件更新完毕的钩子 —— componentDidUpdate")
            }

            // 渲染DOM
            render(){
                console.log("渲染DOM —— render")
                const {num} = this.state
                return (
                    <div>
                        <h1>当前数字为：{num}</h1>
                        <button onClick={this.add}>点我 +1</button>
                        <button onClick={this.death}>卸载组件</button>
                        <button onClick={this.force}>不改变任何状态 强制更新</button>
                    </div>
                )
            }
        }
        // 父组件 A
        class A extends React.Component {
            // 初始化组件
            state = {carName:"奔驰"}
            // 点击换车
            changeCar = () => {
                let {carName} = this.state;
                this.setState({carName:"宝马"})
            }
            render(){
                return (
                    <div>
                        <h1>我是 A 组件</h1>
                        <button onClick={this.changeCar}>点击换车</button>
                        <B carName={this.state.carName} />    
                    </div>
                )
            }
        }
        
        // 子组件 B
        class B extends React.Component {
            // 组件将要接收新的 props
            componentWillReceiveProps(props){
                console.log("组件将要接收新的 props render —— componentWillReceiveProps",props)
            }
            // 控制组件更新的 “阀门”
            shouldComponentUpdate(){
                console.log("控制组件更新的“阀门” —— shouldComponentUpdate")
                return true
            }
            // 组件将要更新的钩子
            componentWillUpdate(){
                console.log("组件将要更新的钩子 —— componentWillUpdate")
            }
            // 组件更新完毕的钩子
            componentDidUpdate(){
                console.log("组件更新完毕的钩子 —— componentDidUpdate")
            }
            render(){
                console.log("render")
                return (
                    <div>
                        <h1>我是 B 组件</h1>
                        <h1>我接收到的参数是：{this.props.carName}</h1>
                    </div>
                )
            }
        }
        
        // 渲染组件
        ReactDOM.render(<A />,document.getElementById("test"))
    </script>
</body>
</html>